﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dapper.Orm;
using Dapper.Data.Service;

namespace Dapper.Data.Implement
{
    public class ActionDataImpl : IActionDateService
    {
        public static DapperDB repo { get { return DapperDB.GetInstance(); } }
        // Multi Fetch
        public List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args) { return repo.Query<T1, T2, TRet>(cb, sql, args).ToList(); }
        public List<TRet> Fetch<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args) { return repo.Query<T1, T2, T3, TRet>(cb, sql, args).ToList(); }
        public List<TRet> Fetch<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args) { return repo.Query<T1, T2, T3, T4, TRet>(cb, sql, args).ToList(); }

        // Multi Query
        public IEnumerable<TRet> Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args) { return repo.Query<TRet>(new Type[] { typeof(T1), typeof(T2) }, cb, sql, args); }
        public IEnumerable<TRet> Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args) { return repo.Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, cb, sql, args); }
        public IEnumerable<TRet> Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args) { return repo.Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, cb, sql, args); }

        // Multi Fetch (SQL builder)
        public List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql) { return Query<T1, T2, TRet>(cb, sql.SQL, sql.Arguments).ToList(); }
        public List<TRet> Fetch<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, Sql sql) { return Query<T1, T2, T3, TRet>(cb, sql.SQL, sql.Arguments).ToList(); }
        public List<TRet> Fetch<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, Sql sql) { return Query<T1, T2, T3, T4, TRet>(cb, sql.SQL, sql.Arguments).ToList(); }

        // Multi Query (SQL builder)
        public IEnumerable<TRet> Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql) { return repo.Query<TRet>(new Type[] { typeof(T1), typeof(T2) }, cb, sql.SQL, sql.Arguments); }
        public IEnumerable<TRet> Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, Sql sql) { return repo.Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, cb, sql.SQL, sql.Arguments); }
        public IEnumerable<TRet> Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, Sql sql) { return repo.Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, cb, sql.SQL, sql.Arguments); }

        // Multi Fetch (Simple)
        public List<T1> Fetch<T1, T2>(string sql, params object[] args) { return repo.Query<T1, T2>(sql, args).ToList(); }
        public List<T1> Fetch<T1, T2, T3>(string sql, params object[] args) { return repo.Query<T1, T2, T3>(sql, args).ToList(); }
        public List<T1> Fetch<T1, T2, T3, T4>(string sql, params object[] args) { return repo.Query<T1, T2, T3, T4>(sql, args).ToList(); }

        // Multi Query (Simple)
        public IEnumerable<T1> Query<T1, T2>(string sql, params object[] args) { return repo.Query<T1>(new Type[] { typeof(T1), typeof(T2) }, null, sql, args); }
        public IEnumerable<T1> Query<T1, T2, T3>(string sql, params object[] args) { return repo.Query<T1>(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, null, sql, args); }
        public IEnumerable<T1> Query<T1, T2, T3, T4>(string sql, params object[] args) { return repo.Query<T1>(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null, sql, args); }

        // Multi Fetch (Simple) (SQL builder)
        public List<T1> Fetch<T1, T2>(Sql sql) { return repo.Query<T1, T2>(sql.SQL, sql.Arguments).ToList(); }
        public List<T1> Fetch<T1, T2, T3>(Sql sql) { return repo.Query<T1, T2, T3>(sql.SQL, sql.Arguments).ToList(); }
        public List<T1> Fetch<T1, T2, T3, T4>(Sql sql) { return repo.Query<T1, T2, T3, T4>(sql.SQL, sql.Arguments).ToList(); }

        // Multi Query (Simple) (SQL builder)
        public IEnumerable<T1> Query<T1, T2>(Sql sql) { return repo.Query<T1>(new Type[] { typeof(T1), typeof(T2) }, null, sql.SQL, sql.Arguments); }
        public IEnumerable<T1> Query<T1, T2, T3>(Sql sql) { return repo.Query<T1>(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, null, sql.SQL, sql.Arguments); }
        public IEnumerable<T1> Query<T1, T2, T3, T4>(Sql sql) { return repo.Query<T1>(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null, sql.SQL, sql.Arguments); }

    }

    public class ActionDateImpl<T> : IActionDateService<T> where T : new()
    {
        public static DapperDB repo { get { return DapperDB.GetInstance(); } }
        public bool IsNew(T modle) { return repo.IsNew(modle); }
        public object Insert(T modle) { return repo.Insert(modle); }
        public void Save(T modle) { repo.Save(modle); }
        public int Update(T modle) { return repo.Update(modle); }
        public int Update(T modle, IEnumerable<string> columns) { return repo.Update(modle, columns); }
        public int Update(string sql, params object[] args) { return repo.Update<T>(sql, args); }
        public int Update(Sql sql) { return repo.Update<T>(sql); }
        public int Delete(T modle) { return repo.Delete(modle); }
        public int Delete(string sql, params object[] args) { return repo.Delete<T>(sql, args); }
        public int Delete(Sql sql) { return repo.Delete<T>(sql); }
        public int Delete(object primaryKey) { return repo.Delete<T>(primaryKey); }
        public bool Exists(object primaryKey) { return repo.Exists<T>(primaryKey); }
        public T SingleOrDefault(object primaryKey) { return repo.SingleOrDefault<T>(primaryKey); }
        public T SingleOrDefault(string sql, params object[] args) { return repo.SingleOrDefault<T>(sql, args); }
        public T SingleOrDefault(Sql sql) { return repo.SingleOrDefault<T>(sql); }
        public T FirstOrDefault(string sql, params object[] args) { return repo.FirstOrDefault<T>(sql, args); }
        public T FirstOrDefault(Sql sql) { return repo.FirstOrDefault<T>(sql); }
        public T Single(object primaryKey) { return repo.Single<T>(primaryKey); }
        public T Single(string sql, params object[] args) { return repo.Single<T>(sql, args); }
        public T Single(Sql sql) { return repo.Single<T>(sql); }
        public T First(string sql, params object[] args) { return repo.First<T>(sql, args); }
        public T First(Sql sql) { return repo.First<T>(sql); }
        public List<T> Fetch(string sql, params object[] args) { return repo.Fetch<T>(sql, args); }
        public List<T> Fetch(Sql sql) { return repo.Fetch<T>(sql); }
        public List<T> Fetch(long page, long itemsPerPage, string sql, params object[] args) { return repo.Fetch<T>(page, itemsPerPage, sql, args); }
        public List<T> Fetch(long page, long itemsPerPage, Sql sql) { return repo.Fetch<T>(page, itemsPerPage, sql); }
        public List<T> SkipTake(long skip, long take, string sql, params object[] args) { return repo.SkipTake<T>(skip, take, sql, args); }
        public List<T> SkipTake(long skip, long take, Sql sql) { return repo.SkipTake<T>(skip, take, sql); }
        public Page<T> Page(long page, long itemsPerPage, string sql, params object[] args) { return repo.Page<T>(page, itemsPerPage, sql, args); }
        public Page<T> Page(long page, long itemsPerPage, Sql sql) { return repo.Page<T>(page, itemsPerPage, sql); }
        public IEnumerable<T> Query(string sql, params object[] args) { return repo.Query<T>(sql, args); }
        public IEnumerable<T> Query(Sql sql) { return repo.Query<T>(sql); }
    }
}
